package com.bright.ghj.overt.task.timely;

import com.bright.ghj.common.util.CollectionUtil;
import com.bright.ghj.common.util.DateUtil;
import com.bright.ghj.common.util.JsonUtils;
import com.bright.ghj.common.util.StringUtil;
import com.bright.ghj.overt.manager.PublicInfoMasterTableManager;
import com.bright.ghj.overt.pojo.dto.PublicInfoMasterTableDTO;
import com.bright.ghj.overt.pojo.dto.PublicInfoSubTableDTO;
import com.bright.ghj.overt.pojo.dto.ZtDTO;
import com.bright.ghj.overt.pojo.po.primary.FileListDFLZ;
import com.bright.ghj.overt.pojo.vo.OpenReportRecordVO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author Tz
 * @date 2024/01/22 15:03
 * @Description 上传廉政的异步任务执行器实现
 */
@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class AsyncCollectPlatformExecutor extends AsyncTaskExecutor {


    private static final String ASYNC_TASK_EXECUTOR_NAME = "上传党廉平台任务处理器";

    private String collectDataUrl;

    /**
     * 当前地区标识
     */
    private String region;

    private JdbcTemplate jdbcTemplatePrimary;
    private JdbcTemplate jdbcTemplateSecond;
    private RestTemplate restTemplate;

    private PlatformTransactionManager transactionManagerPrimary;
    private PlatformTransactionManager transactionManagerSecond;

    private List<FileListDFLZ> fileListDFLZList;

    private ZtDTO ztDTO;

    private PublicInfoMasterTableManager publicInfoMasterTableManager;

    private List<OpenReportRecordVO> auditedData;

    /**
     * 初始化设置执行器名称
     */
    public AsyncCollectPlatformExecutor() {
        super(ASYNC_TASK_EXECUTOR_NAME);
    }


    /**
     * 实际异步执行的任务体抽象方法、由具体的异步任务实现
     * @return            执行结果
     * @throws Exception  可能出现的业务异常
     */
    @Override
    public boolean taskContent() {
        return handleUpload();
    }

    /**
     * 获取季度月份
     * @return  季度月份
     */
    private Integer getQuarterMonth() {
        Integer rvalue = null;

        switch (getMonths()) {
            case 2:
            case 3:
            case 4:
                rvalue = 3;
                break;
            case 5:
            case 6:
            case 7:
                rvalue = 6;
                break;
            case 8:
            case 9:
            case 10:
                rvalue = 9;
                break;
            case 11:
            case 12:
            case 1:
                rvalue = 12;
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + getMonths());
        }
        return rvalue;
    }


    /**
     * 获取采集编号的日期部分的内容
     * @param years     年份
     * @param months    月份
     * @param gkType    公开类型
     * @return          采集编号日期部分内容
     */
    public String getCollectionNumDate(Integer years, Integer months, String gkType) {

        String collectionNumDate = String.valueOf(years);

        if(months == 0) {
            months = months;
        }

        if (StringUtils.equals(gkType, "年")
                || StringUtils.equals(gkType, "年末")) {
            return collectionNumDate;
        }
        if (StringUtils.equals(gkType, "月")) {
            collectionNumDate = collectionNumDate + "-";
            if (months.intValue() < 10) {
                collectionNumDate = collectionNumDate + "0";
            }
            collectionNumDate = collectionNumDate + months;
        }
        if (StringUtils.equals(gkType, "季")) {
            collectionNumDate = collectionNumDate + "-";
            switch (months) {
                case 1:
                case 2:
                case 3:
                    collectionNumDate = collectionNumDate + "A";
                    break;
                case 4:
                case 5:
                case 6:
                    collectionNumDate = collectionNumDate + "B";
                    break;
                case 7:
                case 8:
                case 9:
                    collectionNumDate = collectionNumDate + "C";
                    break;
                case 10:
                case 11:
                case 12:
                    collectionNumDate = collectionNumDate + "D";
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + months);
            }
        }
        if (StringUtils.equals(gkType, "及时")) {
            String dates = null;
            //上传的年份等于当前年
            if (years.equals(Integer.valueOf(DateUtil.getYearOrMonthOrDay(DateUtil.getCurrDate(), 1)))
                    //上传的月份等于当前月
                    && months.equals(Integer.valueOf(DateUtil.getYearOrMonthOrDay(DateUtil
                    .getCurrDate(), 2)))) {
                dates = DateUtil.getCurrentDateStr();
            } else {
                int days = DateUtil.getDaysInMonth(years, months);
                dates = years + "-";
                if(months < 10) {
                    dates = dates + "0";
                }
                dates = dates + months + "-";
                if(days < 10) {
                    dates = dates + "0";
                }
                dates = dates + days;
            }
            collectionNumDate = dates;
        }

        return collectionNumDate;
    }


    /**
     * 执行上传廉政平台逻辑
     * @return 返回执行的结果
     */
    public boolean handleUpload() {

        // 执行上传廉政平台逻辑
        // 还需要区分上传的是党务、事务、还是财务、或者其他类型的大类报表

        //实际执行的业务需要手动开启事务、手动提交回滚
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus primaryStatus = transactionManagerPrimary.getTransaction(def);
        TransactionStatus secondStatus = transactionManagerSecond.getTransaction(def);

        try {
            List<PublicInfoMasterTableDTO> masterTables = new ArrayList<>();

            //记录新增或更新的主表信息 进行上传到远端廉政平台
            List<PublicInfoMasterTableDTO> resultMastTables = new ArrayList<>();

            String threeDistNo = ztDTO.getThreeDistNo();
            String threeZtNo = ztDTO.getThreeZtNo();

            //获取需要上传廉政的公开报表名称列表
            List<String> openTableNames = auditedData.stream()
                    .map(e -> e.getTableName().trim())
                    .distinct()
                    .collect(Collectors.toList());

            //因为上传逻辑是根据公开表为核心， 执行数也跟它有关系，所以进度步长由它决定
            int execCount = fileListDFLZList.size();
            setProgressStepSize(PERCENTAGE / execCount);

            for (FileListDFLZ fileListDFLZ : fileListDFLZList) {

                //推进进度 这里做这个判断是为了将最后的进度交给上传远端廉政平台进行推进
                if (fileListDFLZList.size() - 1 != fileListDFLZList.lastIndexOf(fileListDFLZ)) {
                    advanceProgress();
                }
//                advanceProgress();

                //上传廉政之前执行的配置语句
                if (StringUtil.isNotBlank(fileListDFLZ.getFromBeforeSql())) {
                    log.debug("任务类型: [上传廉政平台], 任务步骤: [上传廉政之前执行的配置语句], 语句: [{}]", fileListDFLZ.getFromBeforeSql());
                    jdbcTemplatePrimary.update(fileListDFLZ.getFromBeforeSql());
                }

                masterTables.clear();

                //没有公开主表信息，跳过
                if (!openTableNames.contains(fileListDFLZ.getTableName())) {
                    log.debug("任务类型: [上传廉政平台], 任务步骤: [校验主表{}配置信息], 结果: [无]", fileListDFLZ.getTableName());
                    continue;
                }

                //数据表名
                String tableName = String.format("\"%s\"", fileListDFLZ.getTableName());
                //公开类型
                String gkType = fileListDFLZ.getGktype();
                //类型名称
                String typeName = fileListDFLZ.getTypeName();
                //目标端表名编码
                String tableNameNo = fileListDFLZ.getXmbm();

                //最小年月份
                Integer minYear = fileListDFLZ.getMinYear();
                Integer minMonth = fileListDFLZ.getMinMonth();

                //月份字段
                String monthColumn = "";
                //财务公开的查询结束语句
                String sqlCwgkEnd = "";
                //查询最小年月份的条件 查询的数据需要大于这个条件
                String minYearMonthSql = "";

                //根据配置的字段设置查询条件  上传的表要大于最小年月
                if (minMonth != null && minMonth != 0) {
                    minYearMonthSql = " and years * 100 + months >= " + minYear;
                    if (minMonth < 10) {
                        minYearMonthSql = minYearMonthSql + "0";
                    }
                    minYearMonthSql = minYearMonthSql + minMonth;
                } else {
                    minYearMonthSql = " and years >= " + minYear;
                }

                //如果是年表默认月份为0
                if (StringUtils.equals(typeName, "年报")
                        || StringUtils.equals(typeName, "年初报")) {
                    monthColumn = "0";
                } else {
                    monthColumn = "months";
                }

                //根据当前请求的条件拼接查询语句
                sqlCwgkEnd = " and years=" + getYears();
                if (!StringUtils.equals(gkType, "年")) {
                    if (StringUtils.equals(gkType, "年末")) {
                        sqlCwgkEnd = sqlCwgkEnd + " and months = 12";
                    } else if (StringUtils.equals(gkType, "季")) {
                        sqlCwgkEnd = sqlCwgkEnd + " and months = " + getQuarterMonth();
                    } else {
                        sqlCwgkEnd = sqlCwgkEnd + " and months = " + getMonths();
                    }
                }


                String selectRealSql = "select years,"
                        + monthColumn
                        + " as months, zth from "
                        + tableName
                        + " where zth = '"
                        + getZtId()
                        + "' and zth not in (select zth from tDFLZ_GKXXZB where dwbm='"
                        + threeDistNo + "' and GKXMBM='" + tableNameNo
                        + "' and years=" + tableName + ".years";
                if (!StringUtils.equals(typeName, "年报")
                        && !StringUtils.equals(typeName, "年初报")) {
                    selectRealSql = selectRealSql + " and months = " + tableName + ".months";
                }
                selectRealSql = selectRealSql + ")";

                if (StringUtils.equals(gkType, "年末")) {
                    selectRealSql = selectRealSql + " and months = 12";
                }
                if (StringUtils.equals(typeName, "季报")) {
                    selectRealSql = selectRealSql + " and (months = 3 or months = 6 or months = 9 or months = 12)";
                }

                selectRealSql = selectRealSql + sqlCwgkEnd + minYearMonthSql;

                selectRealSql = selectRealSql + " group by years";
                //如果不是年表 则需要按月份分组
                if (!StringUtils.equals(typeName, "年报") && !StringUtils.equals(typeName, "年初报")) {
                    selectRealSql = selectRealSql + ",months";
                }
                selectRealSql = selectRealSql + ",zth";

                //查询实际数据的年月、账套号
                log.debug("任务类型: [上传廉政平台], 任务步骤: [查询实际数据的年月、账套号], 语句: [{}]", selectRealSql);
                List<Map<String, Object>> realResult = jdbcTemplatePrimary.queryForList(selectRealSql);

                // 查询的数据为空且符合条件，则给默认值 只需要保证生成主表记录即可
                if (CollectionUtil.isEmpty(realResult) && ("月".equals(gkType)
                        || ("及时".equals(gkType))
                        || ("季".equals(gkType) && (getMonths() == 3 || getMonths() == 6 || getMonths() == 9 || getMonths() == 12))
                        || ("年末".equals(gkType) && (getMonths() == 12))
                        || ("年".equals(gkType) && (getMonths() == 12))
                        || ("年初报".equals(gkType) && (getMonths() == 1)))) {
                    realResult = new ArrayList<>();
                    Map<String, Object> tempHasMap = new HashMap<>(3);
                    tempHasMap.put("years", getYears());
                    tempHasMap.put("months", "months".equalsIgnoreCase(monthColumn) ? getMonths() : 0);
                    realResult.add(tempHasMap);
                }


                if (CollectionUtil.isEmpty(realResult)) {
                    log.debug("任务类型: [上传廉政平台], 任务步骤: [查询实际数据的年月、账套号], 结果: [无数据]");
                    continue;
                }

                //=============== 添加相关的主表信息 dflz_gkxxzb ===============
                //获取查询结果的年月份 因为年表不会根据
                for (Map<String, Object> tempMap : realResult) {
                    Integer years = Integer.valueOf(tempMap.get("years").toString().split("\\.")[0]);
                    Integer months = Integer.valueOf(tempMap.get("months").toString().split("\\.")[0]);

                    //获取采集编号的时间部分
                    String collectNumDate = getCollectionNumDate(years, months, gkType);

                    //完整的采集编号
                    String completeCollectNum = threeDistNo + "-"
                            + threeZtNo + "-"
                            + tableNameNo + "-"
                            + collectNumDate;

                    //生成一条公开信息主表
                    PublicInfoMasterTableDTO publicInfoMasterTable = new PublicInfoMasterTableDTO();
                    publicInfoMasterTable.setCjbh(completeCollectNum);
                    publicInfoMasterTable.setDwbm(threeDistNo);
                    publicInfoMasterTable.setZtdwbh(threeZtNo);
                    publicInfoMasterTable.setGkxmbm(tableNameNo);
                    publicInfoMasterTable.setXxfssj(collectNumDate);
                    publicInfoMasterTable.setZbr(ztDTO.getZbr());
                    publicInfoMasterTable.setDwfzr(ztDTO.getDwfzr());
                    publicInfoMasterTable.setKjxm(ztDTO.getKjxm());
                    publicInfoMasterTable.setCnxm(ztDTO.getCnxm());
                    publicInfoMasterTable.setJdxz(ztDTO.getJdxz());
                    publicInfoMasterTable.setBssj(DateUtil.getCurrDate());
                    publicInfoMasterTable.setSjcz(1);
                    publicInfoMasterTable.setSjjhbz(0);
                    publicInfoMasterTable.setByzda(ztDTO.getCwfzr());
                    masterTables.add(publicInfoMasterTable);
                }

                //没有主表记录 跳过
                if (CollectionUtil.isEmpty(masterTables)) {
                    continue;
                }

                //处理子表数据
                List<PublicInfoSubTableDTO> subTableDTOS = new ArrayList<>();

                //循环主表处理子表数据
                for (PublicInfoMasterTableDTO masterTable : masterTables) {

                    String subTableName = "DFLZ_" + masterTable.getGkxmbm() + "";

                    //删除旧的子表数据
                    String deleteSubSql = "delete from " + subTableName + " where 1 = 1"
                            + " and cjbh = ? ";
                    log.debug("任务类型: [上传廉政平台], 任务步骤: [删除旧的'{}'子表数据], 语句: [{}]", subTableName, deleteSubSql);
                    jdbcTemplateSecond.update(deleteSubSql, new Object[]{masterTable.getCjbh()});

                    String monthSql = "";
                    if (StringUtils.equals(typeName, "年报")
                            || StringUtils.equals(typeName, "年初报")) {
                    } else {
                        monthSql = " and months=" + getMonths();
                    }

                    String fromSql = fileListDFLZ.getFromSql();
                    String fromSqlSub = " and zth = '" + ztDTO.getZtId()
                            + "' and years = " + getYears()
                            + monthSql + " " + fileListDFLZ.getFromOrderSql();
                    String toSql = fileListDFLZ.getToSql();
                    fromSql = fromSql + fromSqlSub;

                    //查询出需要转入的子表数据
                    log.debug("任务类型: [上传廉政平台], 任务步骤: [查询出需要转入的子表数据], 语句: [{}]", fromSql);
                    List<Map<String, Object>> fromDataList = jdbcTemplatePrimary.query(fromSql, new LinkedHashMapRowMapper());

                    //TODO 这里需要获取用户的配置 空表是否也允许上传廉政平台
                    if (CollectionUtil.isEmpty(fromDataList)) {
                        log.debug("任务类型: [上传廉政平台], 任务步骤: [空表'{}'处理]", tableName);
                        resultMastTables.add(masterTable);
                        //进行更新或新增
                        publicInfoMasterTableManager.save(masterTable);
                        continue;
                    }

//                    List<String> fromSqlFields = fromDataList.get(0).keySet().stream().collect(Collectors.toList());
//                    log.info("表: [{}],  来源字段: [{}]", masterTable, fromSqlFields);

                    String toSqlFields = toSql;

                    //需要对toSql 做处理 构建出插入语句
                    if (StringUtil.isNotBlank(toSql)
                            && toSql.toLowerCase().contains("select")
                            && toSql.toLowerCase().contains("from")) {
                        toSqlFields = extractFieldsFromSQL(toSql);
                        log.debug("任务类型: [上传廉政平台], 任务步骤: [抽取插入到'{}'表的字段], 结果: [{}]", subTableName, toSqlFields);
                    }
//                    log.info("表: [{}],  插入目标字段: [{}]", subTableName, toSqlFields);


//                    PublicInfoSubTableDTO publicInfoSubTableDTO = new PublicInfoSubTableDTO();
//                    publicInfoSubTableDTO.setCjbh(masterTable.getCjbh());
//                    publicInfoSubTableDTO.setSubTables(fromDataList);
//                    subTableDTOS.add(publicInfoSubTableDTO);

                    int orderNum = 0;
                    String lastItemName1 = null;
                    String lastItemNum1 = null;

                    String lastItemName2 = null;
                    String lastItemNum2 = null;
                    //构建插入语句
                    for (Map<String, Object> subTable : fromDataList) {
                        //需要添加必须的字段
                        orderNum++;
                        subTable.put("pxh", orderNum);
                        subTable.put("cjbh", masterTable.getCjbh());

                        //需要特殊处理， 额外的插入字段需要自己添加
                        if(fileListDFLZ.getIsKmdm()) {

                            if (StringUtil.isNotBlank(fileListDFLZ.getKmdm1Name())) {
                                //源端科目带代号的值
                                Object itemNumValue = subTable.get(fileListDFLZ.getKmdm1Name());
                                Object itemNameValue = subTable.get(fileListDFLZ.getXm1Name());

                                String itemNumValueStr = itemNumValue == null ? null : String.valueOf(itemNumValue);
                                String itemNameValueStr = itemNameValue == null ? null : String.valueOf(itemNameValue);

                                //如果科目代号的值为空 则自己新增一个值
                                if (StringUtil.isBlank(itemNumValueStr)) {
                                    //获取新的项目编号
                                    itemNumValueStr = getNewItemNum(fileListDFLZ, lastItemName1, itemNameValueStr, lastItemNum1, orderNum);
                                    subTable.put(fileListDFLZ.getKmdm1Name(), itemNumValueStr);
                                }

                                if(StringUtils.trimToEmpty(itemNumValueStr).length() >= 3) {
                                    String substring = StringUtils.substring(itemNumValueStr, 0, itemNumValueStr.length() - 3);
                                    subTable.put(fileListDFLZ.getSjkmdm1Name()
                                            , StringUtil.isBlank(substring) ? null : substring);
                                    lastItemNum1 = itemNumValueStr;
                                    lastItemName1 = itemNameValueStr;
                                } else {
                                    subTable.put(fileListDFLZ.getSjkmdm1Name(), null);
                                }
                                subTable.put(fileListDFLZ.getKmjb1Name(), Math.round(StringUtils.trimToEmpty(itemNumValueStr).length() / 3));
                            }


                            if (StringUtil.isNotBlank(fileListDFLZ.getKmdm2Name())) {
                                //源端科目带代号的值
                                Object itemNumValue = subTable.get(fileListDFLZ.getKmjb2Name());
                                Object itemNameValue = subTable.get(fileListDFLZ.getXm2Name());

                                String itemNumValueStr = itemNumValue == null ? null : String.valueOf(itemNumValue);
                                String itemNameValueStr = itemNameValue == null ? null : String.valueOf(itemNameValue);

                                //如果科目代号的值为空 则自己新增一个值
                                if (StringUtil.isBlank(itemNumValueStr)) {
                                    //获取新的项目编号
                                    itemNumValueStr = getNewItemNum(fileListDFLZ, lastItemName2, itemNameValueStr, lastItemNum2, orderNum);
                                    subTable.put(fileListDFLZ.getKmdm2Name(), itemNumValueStr);
                                }

                                if(StringUtils.trimToEmpty(itemNumValueStr).length() >= 3) {
                                    String substring = StringUtils.substring(itemNumValueStr, 0, itemNumValueStr.length() - 3);
                                    subTable.put(fileListDFLZ.getSjkmdm2Name()
                                            , StringUtil.isBlank(substring) ? null : substring);
                                    lastItemNum2 = itemNumValueStr;
                                    lastItemName2 = itemNameValueStr;
                                } else {
                                    subTable.put(fileListDFLZ.getSjkmdm2Name(), null);
                                }
                                subTable.put(fileListDFLZ.getKmjb2Name(), Math.round(StringUtils.trimToEmpty(itemNumValueStr).length() / 3));
                            }

                        }

                        List<Object> values = new ArrayList<>(subTable.values());
                        String collect = values.stream().map(e -> "?").collect(Collectors.joining(","));
                        String insertSql = "insert into " + subTableName + " ( " + toSqlFields + " ) values (" + collect + ")";
//                        log.info("表: [{}],  插入语句: [{}]", subTableName, insertSql);
//                        log.info("表: [{}],  插入值: [{}]", subTableName, values);

                        log.debug("任务类型: [上传廉政平台], 任务步骤: [插入'{}'子表数据], 语句: [{}]", subTableName, insertSql);
                        Object[] array = values.toArray(new Object[values.size()]);
                        jdbcTemplateSecond.update(insertSql, array);
                    }

                    resultMastTables.add(masterTable);
                    //进行更新或新增
                    publicInfoMasterTableManager.save(masterTable);
                }
            }

            // 提交事务
            //先进后出提交 否则会出现：Transaction synchronization is not active的错误
            transactionManagerSecond.commit(secondStatus);
            transactionManagerPrimary.commit(primaryStatus);


            //上面的操作先提交事务 因为是先上传到本地廉政平台 后面才是推送到远端廉政平台
            //网络请求上传到远端廉政平台
            boolean uploadFlag = scanPubInfoData(resultMastTables);

            if (uploadFlag) {
                //推进最后的进度
                advanceProgress();
            }

            //根据自己的业务情况进行返回
            return uploadFlag;
        } catch (Exception e) {
            e.printStackTrace();
            // 回滚事务
            //先进后出提交 否则会出现：Transaction synchronization is not active的错误
            transactionManagerSecond.rollback(secondStatus);
            transactionManagerPrimary.rollback(primaryStatus);
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取查询的sql语句中 查询字段的内容
     * @param sql   需要从中获取的sql查询语句
     * @return      查询字段的内容
     */
    public String extractFieldsFromSQL(String sql) {
        String pattern = "select\\s+(.*?)\\s+from";
        Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(sql);
        if (m.find()) {
            return m.group(1);
        } else {
            return "";
        }
    }


    /**
     * 获取新的项目编号
     * @param fileListDFLZ 公开表配置内容
     * @param lastItemName 上一条数据的项目名称
     * @param itemName     当前项目名称
     * @param lastItemNum  上一条数据的项目编号
     * @param row          当前是第几条数据
     * @return             新的项目编号
     */
    public String getNewItemNum(FileListDFLZ fileListDFLZ, String lastItemName, String itemName, String lastItemNum, int row) {
        String newItemNum = null;

        String endResult = null;
        Integer pxmSpaceSize = null;
        Integer xmSpaceSize = null;

        if (lastItemName == null) {
            lastItemName = "";
        }
        if (itemName == null) {
            itemName = "";
        }

        lastItemName = StringUtils.trimToEmpty("1" + lastItemName).substring(1);
        itemName = StringUtils.trimToEmpty("1" + itemName).substring(1);

        pxmSpaceSize = getSpaceSize(lastItemName);
        xmSpaceSize = getSpaceSize(itemName);

        if(StringUtils.isEmpty(lastItemNum)) {
            lastItemNum = String.valueOf(row - 1);
            while(lastItemNum.length() < 3) {
                lastItemNum = "0" + lastItemNum;
            }
        }

        if (StringUtils.isEmpty(itemName)) {
            return null;
        }

        if (pxmSpaceSize < xmSpaceSize) {
            newItemNum = lastItemNum + "001";
            return newItemNum;
        }
        if (pxmSpaceSize.equals(xmSpaceSize)) {
            newItemNum = lastItemNum;
        }

        if(StringUtil.isNotBlank(newItemNum)) {
            try {
                endResult = String.valueOf(Integer.parseInt(StringUtils.right(newItemNum, 3)) + 1);
            } catch(Exception e) {
                e.printStackTrace();
            }
            while(endResult.length() < 3) {
                endResult = "0" + endResult;
            }
            newItemNum = StringUtils.substring(newItemNum, 0, newItemNum.length() - 3) + endResult;
        }
        return newItemNum;
    }


    /**
     * 获取字符串从左开始有多少个连续的空格字符
     * @param source 需要获取的字符串
     * @return       空格字符数量
     */
    private Integer getSpaceSize(String source) {
        int count = 0;
        for (int i = 0; i < source.length(); i++) {
            if (source.charAt(i) == ' ') {
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    /**
     * 按顺序返回
     */
    static class LinkedHashMapRowMapper implements RowMapper<Map<String, Object>> {
        @Override
        public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
            Map<String, Object> map = new LinkedHashMap<>();
            // 将查询结果映射到 LinkedHashMap
            int columnCount = rs.getMetaData().getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = rs.getMetaData().getColumnName(i);
                Object columnValue = rs.getObject(i);
                map.put(columnName, columnValue);
            }
            return map;
        }
    }


    /**
     * 上传到廉政平台 未重试版本
     * @param publicInfoMasterTableDTOS 需要上传的主表信息
     * @return                          返回上传结果
     */
    public boolean scanPubInfoData(List<PublicInfoMasterTableDTO> publicInfoMasterTableDTOS) {

        try {
            //如果没有数据需要操作
            if(CollectionUtil.isEmpty(publicInfoMasterTableDTOS)) {
                log.info("上传到远端廉政平台 - [无上传公开数据,结束操作!]");
                this.setErrorInfo("上传到远端廉政平台 - 无上传公开数据,结束操作!");
                return false;
            }

            //将对象的采集编号作为新的list集合
            List<String> cjbhList = publicInfoMasterTableDTOS.stream().map(PublicInfoMasterTableDTO::getCjbh).collect(Collectors.toList());


            //获取要校验的数据状态
            JsonResult checkJsonResult = getNeedCheckData(cjbhList);

            List<Map<String, Object>> checkList = JsonUtils.parseObject((String) checkJsonResult.getDataResult(), List.class);

            //校验成功
            if(checkJsonResult.getResultCode().equals(1)) {

                log.debug("上传到远端廉政平台 - [开始处理校验成功的采集编号!]");


                //在市平台查询到的数据的采集编号列表
                List<String> checkStrList = checkList.stream().map(e -> (String) e.get("cjid")).collect(Collectors.toList());

                log.info("上传到远端廉政平台 - [获取要校验的数据成功] - [采集编号列表:{}]", checkJsonResult);

                //更新在市平台查不到数据的错误
                List<PublicInfoMasterTableDTO> noFromServiceData = new ArrayList<>();
                noFromServiceData = publicInfoMasterTableDTOS.stream()
                        .filter(f -> !checkStrList.contains(f.getCjbh())).collect(Collectors.toList());
                for(PublicInfoMasterTableDTO temp : noFromServiceData) {
                    temp.setBssj(DateUtil.getCurrDate());
                    temp.setCwrz(DateUtil.getNowString() + " 校验失败：市平台不存在该采集编号:[" + temp.getCjbh() + "]");
                    temp.setSjjhbz(-1);

                    publicInfoMasterTableManager.save(temp);
                }

                //去除不符合条件的数据
                List<Map<String, Object>> successList = checkList.stream()
                        .filter(f -> Objects.isNull(f.get("status"))
                        || (Integer) f.get("status") == 0
                        || (Integer) f.get("status") == 2).collect(Collectors.toList());

                //更新在市平台查到数据却不符合的错误
                List<Map<String, Object>> inConformityData = checkList.stream()
                        .filter(f -> (!Objects.isNull(f.get("status"))) && ((Integer) f.get("status") == 4
                        || (Integer) f.get("status") == 6)).collect(Collectors.toList());

                for(Map<String, Object> tempMap : inConformityData) {
                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById((String) tempMap.get("cjid"));
                    temp.setBssj(DateUtil.getCurrDate());
                    temp.setCwrz(DateUtil.getNowString() + " 校验失败：该数据已发布或已审核");
                    temp.setSjjhbz(1);
                    publicInfoMasterTableManager.save(temp);
                }

                //更新不需要发布的情况
                List<Map<String, Object>> noPublicData = checkList.stream()
                        .filter(f -> (!Objects.isNull(f.get("status"))) && (Integer) f.get("status") == 100).collect(Collectors.toList());
                for(Map<String, Object> tempMap : noPublicData) {
                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById((String) tempMap.get("cjid"));
                    temp.setBssj(DateUtil.getCurrDate());
                    temp.setCwrz(DateUtil.getNowString() + " 校验失败：市平台不需要公布!");
                    temp.setSjjhbz(1);
                    publicInfoMasterTableManager.save(temp);
                }

                //在返回符合条件的cjid集合
                List<String> cjidList = successList.stream().map(e -> (String) e.get("cjid"))
                        .collect(Collectors.toList());


                //在去除要采集数据结果集中的不符合条件的数据
                publicInfoMasterTableDTOS = publicInfoMasterTableDTOS.stream()
                        .filter(f -> cjidList.contains(f.getCjbh())).collect(Collectors.toList());

                log.debug("上传到远端廉政平台 - [处理校验成功的采集编号结束!]");

            } else {

                log.debug("上传到远端廉政平台 - [开始处理校验失败的采集编号!]");


                log.info("上传到远端廉政平台 - [获取要校验的数据失败] - [采集编号列表:{}]", checkJsonResult);

                //检查失败的情况
                //只更新错误的
                //更改为重试
                for(Map<String, Object> tempMap : checkList) {
                    String cjbh = (String) tempMap.get("cjid");

                    String cjbhTemp = (String) tempMap.get("cjid");

                    //可能是转换后的采集编号 检查出错的
                    if(StringUtil.contains(cjbh, "-SHE_")) {
                        cjbhTemp = StringUtil.replace(cjbh, "-SHE_", "-CUN_");
                    }
                    if(StringUtil.contains(cjbh, "-ZZGS_")) {
                        cjbhTemp = StringUtil.replace(cjbh, "-ZZGS_", "-CUN_");
                    }

                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById(cjbhTemp);
                    temp.setCjbh(cjbhTemp);
                    temp.setCwrz(DateUtil.getNowString()
                            + "检查采集编号时出错,请检查该["
                            + cjbh
                            + "]采集编号是否有异常！！");

                    temp.setSjjhbz(-1);
                    temp.setBssj(DateUtil.getCurrDate());

                    publicInfoMasterTableManager.save(temp);
                }

                log.debug("上传到远端廉政平台 - [处理失败的采集编号结束!]");
                this.setErrorInfo("上传到远端廉政平台 - 采集编号校验失败!");
                return false;
            }


            //如果筛选过后没有数据 表示没有需要处理的数据了
            if(CollectionUtil.isEmpty(publicInfoMasterTableDTOS)) {
                log.info("上传到远端廉政平台 - [校验采集编号处理成功后没有需要上传的公开数据, 结束操作!]");
                return true;
            }

            //采集子表的记录
            List<Map<String, Object>> subCollectDataList = getCollectSubTableData(publicInfoMasterTableDTOS);

            List<String> cjbhLists = new ArrayList<>();
            cjbhLists = subCollectDataList.stream().map(e -> (String) e.get("cjbh")).collect(Collectors.toList());


            //上传采集好的子表的数据
            JsonResult dataResult = operationCollectData(subCollectDataList);
            log.info("上传到远端廉政平台 - [成功上传公开数据!] - [上传的公开数据列表:{}]", cjbhList);


            List<Map> responseDtoList
                    = JsonUtils.parseArray((String) dataResult.getDataResult(), Map.class);

            //根据返回的结果状态进行处理 数据是否操作完成
            //如果数据操作成功
            if(dataResult.getResultCode().equals(1)) {

                log.debug("上传到远端廉政平台 - [开始处理子表数据采集成功的情况!]");

                List<String> successCjidList = responseDtoList.stream().map(e -> (String) e.get("cjid")).collect(Collectors.toList());
                log.info("上传到远端廉政平台 - [成功上传公开子表数据!] - [上传的公开数据列表:{}]", successCjidList);

                //更新主表数据操作结果信息
                for(Map collectDataResponseDto : responseDtoList) {
                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById((String) collectDataResponseDto.get("cjid"));
                    String operationMessage = (String) collectDataResponseDto.get("operationMessage");
                    temp.setBssj(DateUtil.getCurrDate());
                    temp.setSjjhbz((Integer) collectDataResponseDto.get("sjjhbz"));
                    temp.setCwrz(operationMessage);

                    if(operationMessage.contains("子表已录入数据")) {

                        temp.setSjjhbz(-1);
                    }

                    publicInfoMasterTableManager.save(temp);
                    //[{'cjid':'aaa','sjjhbz':1,'message':'数据交换成功'}
                    // ,{'cjid':'bbb','sjjhbz':-1,'message':'验证失败：公开项目编号【ZZGS_ZDKJJSYDLZSR】没有在【dflz_spv_cw_setup】表中配置！'}]
                }

                log.debug("上传到远端廉政平台 - [处理子表数据采集成功!]");

            } else {

                log.debug("上传到远端廉政平台 - [开始处理子表数据采集失败的情况!]");

                //获取返回结果集的采集编号列表 错误的采集编号列表
                List<String> operationErrorCjBH = responseDtoList.stream().map(e -> (String) e.get("cjid")).collect(Collectors.toList());

                //获取排除错误采集列表后的采集列表
                cjbhLists = cjbhLists.stream().filter(e -> !operationErrorCjBH.contains(e)).collect(Collectors.toList());

                //循环不是错误的采集列表 更新为初始状态
                for(String cjbh : cjbhLists) {
                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById(cjbh);
                    temp.setCjbh(cjbh);
                    temp.setBssj(new Date());

                    publicInfoMasterTableManager.save(temp);
                }

                //更新主表数据操作结果信息
                for(Map collectDataResponseDto : responseDtoList) {

                    String cjid = (String) collectDataResponseDto.get("cjid");
                    String operationMessage = (String) collectDataResponseDto.get("operationMessage");

                    PublicInfoMasterTableDTO temp = publicInfoMasterTableManager.findById(cjid);
                    temp.setCwrz(operationMessage);

                    //则重试时间为当前的时间加配置重试的时间
                    temp.setSjjhbz(-1);
                    temp.setBssj(DateUtil.getCurrDate());

                    publicInfoMasterTableManager.save(temp);
                }

                log.debug("上传到远端廉政平台 - [处理子表数据采集失败结束!]");
            }

            return true;
        }
        catch (ResourceAccessException e) {
            log.info("上传到远端廉政平台 - [网络连接异常!] - [{}]", e.getMessage());
            this.setErrorInfo("网络连接异常!");
            for(PublicInfoMasterTableDTO temp : publicInfoMasterTableDTOS) {
                temp.setBssj(DateUtil.getCurrDate());
                temp.setCwrz(DateUtil.getNowString() + " 网络异常:[" + temp.getCjbh() + "]");
                temp.setSjjhbz(-1);
                publicInfoMasterTableManager.save(temp);
            }
            e.printStackTrace();
            return false;
        }
        catch (Exception e) {
            log.info("上传到远端廉政平台 - [执行异常!] - [{}]", e.getMessage());
            this.setErrorInfo("执行异常!");
            for(PublicInfoMasterTableDTO temp : publicInfoMasterTableDTOS) {
                temp.setBssj(DateUtil.getCurrDate());
                temp.setCwrz(DateUtil.getNowString() + " 执行异常:[" + temp.getCjbh() + "]");
                temp.setSjjhbz(-1);
                publicInfoMasterTableManager.save(temp);
            }
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 调用接口获取需要校验的数据
     * @param cjbhList 采集编号列表
     * @return         返回需要校验的数据
     */
    public JsonResult getNeedCheckData(List<String> cjbhList) {

        log.debug("上传到远端廉政平台 - [网络请求] - [开始校验采公开主表的采集编号]");

        //设置请求头，请求类型为json
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        //设置请求参数
        HashMap<String, Object> getNeedCheckDataParam = new HashMap<>(5);
        getNeedCheckDataParam.put("jcbhList", cjbhList);

        //用HttpEntity封装整个请求报文
        HttpEntity<HashMap<String, Object>> getNeedCheckDataRequest = new HttpEntity<>(getNeedCheckDataParam, headers);

        //获取要交换的数据状态
        JsonResult checkJsonResult = restTemplate.postForObject(collectDataUrl + "/getNeedCheckData"
                , getNeedCheckDataRequest
                , JsonResult.class
                , getNeedCheckDataParam);

        log.debug("上传到远端廉政平台 - [网络请求] - [校验采公开主表的采集编号结束]");
        return checkJsonResult;
    }


    /**
     * 根据主表扫描子表数据
     * @param publicInfoMasterTables 主表集合
     * @return                       返回dto封装的数据
     */
    public List<Map<String, Object>> getCollectSubTableData(List<PublicInfoMasterTableDTO> publicInfoMasterTables) {

        log.debug("上传到远端廉政平台 - [开始查询子表数据]");
        List<Map<String, Object>> subCollectDataList = new ArrayList<>();
        //循环主表 根据表名和查询采集编号查询子表数据
        for(PublicInfoMasterTableDTO publicInfoMasterTableDTO : publicInfoMasterTables) {
            Map<String, Object> subCollectData = new LinkedHashMap<>();

            String subDataSql = "select * from ${tableName} where cjbh = ?";
            List<Map<String,Object>> subList = jdbcTemplateSecond.queryForList(subDataSql.replace("${tableName}"
                    , "DFLZ_" + publicInfoMasterTableDTO.getGkxmbm())
                    , publicInfoMasterTableDTO.getCjbh());

            subCollectData.put("cjbh", publicInfoMasterTableDTO.getCjbh());
            subCollectData.put("gkxmbm", publicInfoMasterTableDTO.getGkxmbm());
            subCollectData.put("sjcz", publicInfoMasterTableDTO.getSjcz());
            subCollectData.put("zbr", publicInfoMasterTableDTO.getZbr());
            subCollectData.put("dwfzr", publicInfoMasterTableDTO.getDwfzr());
            subCollectData.put("kjxm", publicInfoMasterTableDTO.getKjxm());
            subCollectData.put("cnxm", publicInfoMasterTableDTO.getCnxm());
            subCollectData.put("jdxz", publicInfoMasterTableDTO.getJdxz());
            subCollectData.put("cwfzr", publicInfoMasterTableDTO.getByzda());

            subCollectData.put("subData", subList);
            subCollectData.put("region",region);

            subCollectDataList.add(subCollectData);
        }
        log.debug("上传到远端廉政平台 - [结束查询子表数据]");
        return subCollectDataList;
    }


    /**
     * 操作采集好的子表的数据
     * @param subCollectDataList 指标数据
     * @return                   返回数据操作的结果
     */
    public JsonResult operationCollectData(List<Map<String, Object>> subCollectDataList) {

        log.debug("上传到远端廉政平台 - [网络请求] - [开始上传子表数据到远端廉政平台]");

        //设置请求头，请求类型为json
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        //设置请求参数
        HashMap<String, Object> operationCollectDataParam = new HashMap<>(5);
//        operationCollectDataParam.put("subcollectData", JSONUtil.toJsonStr(subCollectDataList));

        //由于map的value值为空在转json时key值会被忽略 需要配置转换时不忽略null值
        String subCollectDataListJson = JsonUtils.toJsonString(subCollectDataList);

        operationCollectDataParam.put("subcollectData", subCollectDataListJson);

        //用HttpEntity封装整个请求报文
        HttpEntity<HashMap<String, Object>> operationCollectDataParamRequest = new HttpEntity<>(operationCollectDataParam, headers);

        //请求接口 将采集的数据上传
        JsonResult dataResult = restTemplate.postForObject(collectDataUrl + "/operationCollectData"
                , operationCollectDataParamRequest
                , JsonResult.class
                , operationCollectDataParam);

        log.debug("上传到远端廉政平台 - [网络请求] - [结束上传子表数据到远端廉政平台]");

        return dataResult;

    }

    @Getter
    @Setter
    @Data
    static class JsonResult<T> {
        /**
         响应码
         */
        private Integer resultCode;

        /**
         * 响应信息
         */
        private String message;

        /**
         * 响应数据
         */
        private T dataResult;

    }


}
